//package com.cloud.lan.config;
//
//import com.google.common.collect.Maps;
//
//import org.apache.commons.io.IOUtils;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.core.Ordered;
//import org.springframework.http.HttpStatus;
//import org.springframework.web.filter.OncePerRequestFilter;
//import org.springframework.web.util.ContentCachingRequestWrapper;
//import org.springframework.web.util.ContentCachingResponseWrapper;
//import org.springframework.web.util.WebUtils;
//
//import java.io.IOException;
//import java.net.URI;
//import java.net.URISyntaxException;
//import java.time.LocalDateTime;
//import java.util.Enumeration;
//import java.util.HashMap;
//import java.util.Map;
//import java.util.Objects;
//
//import javax.servlet.FilterChain;
//import javax.servlet.ServletException;
//import javax.servlet.http.HttpServletRequest;
//import javax.servlet.http.HttpServletResponse;
//
//import cn.hutool.core.date.DateUtil;
//import cn.hutool.core.date.TimeInterval;
//import cn.hutool.json.JSONUtil;
//import lombok.Data;
//import lombok.experimental.Accessors;
//
///**
// * *********************************************************
// *
// * @Author <a href="mailto:xyqierkang@gmail.com">ErKang Qi</a>
// * @Date Created in 2020/1/31 17:51
// * @Title HttpTraceLogFilter.java
// * <p>Description: [ 继承 spring 过滤器 OncePerRequestFilter 实现自定义过滤器 从而实现操作日志Aop效果 ] </p>
// * <p>Blog: https://www.qekang.com</p>
// * <p>Inc:  </p>
// * <p>Copyright:    </p>
// * <p>Department: Product development </p>
// * *********************************************************
// */
//@Configuration
//public class HttpTraceLogFilter extends OncePerRequestFilter implements Ordered {
//
//    private static final String IGNORE_CONTENT_TYPE = "multipart/form-data";
//
//    protected Logger log = LoggerFactory.getLogger(getClass());
//
//    @Override
//    public int getOrder() {
//        return Ordered.LOWEST_PRECEDENCE - 10;
//    }
//
//    private HttpTraceLog getUserBasicInfo(HttpTraceLog traceLog, HttpServletRequest request) {
//        Object userId = request.getAttribute("userId");
//        if (null != userId) {
//            traceLog.setUserId(userId.toString());
//        }
//        Object shopId = request.getAttribute("shopId");
//        if (null != shopId) {
//            traceLog.setShopId(shopId.toString());
//        }
//        Object deviceNumber = request.getAttribute("deviceNumber");
//        if (null != deviceNumber) {
//            traceLog.setDeviceNumber(deviceNumber.toString());
//        }
//        Object clientVersion = request.getAttribute("clientVersion");
//        if (null != clientVersion) {
//            traceLog.setClientVersion(clientVersion.toString());
//        }
//        return traceLog;
//    }
//
//    private boolean isRequestValid(HttpServletRequest request) {
//        try {
//            new URI(request.getRequestURL().toString());
//            return true;
//        } catch (URISyntaxException ex) {
//            return false;
//        }
//    }
//
//    private String getRequestBody(HttpServletRequest request) {
//        String requestBody = "";
//        ContentCachingRequestWrapper wrapper = WebUtils.getNativeRequest(request, ContentCachingRequestWrapper.class);
//        if (wrapper != null) {
//            try {
//                requestBody = IOUtils.toString(wrapper.getContentAsByteArray(), wrapper.getCharacterEncoding());
//            } catch (IOException e) {
//                log.error("getRequestBody IOException", e);
//            }
//        }
//        return requestBody;
//    }
//
//    private String getResponseBody(HttpServletResponse response) {
//        String responseBody = "";
//        ContentCachingResponseWrapper wrapper = WebUtils.getNativeResponse(response, ContentCachingResponseWrapper.class);
//        if (wrapper != null) {
//            try {
//                responseBody = IOUtils.toString(wrapper.getContentAsByteArray(), wrapper.getCharacterEncoding());
//            } catch (IOException e) {
//                log.error("getResponseBody IOException", e);
//            }
//        }
//        return responseBody;
//    }
//
//    private void updateResponse(HttpServletResponse response) throws IOException {
//        ContentCachingResponseWrapper responseWrapper = WebUtils.getNativeResponse(response, ContentCachingResponseWrapper.class);
//        Objects.requireNonNull(responseWrapper).copyBodyToResponse();
//    }
//
//    @Override
//    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
//            throws ServletException, IOException {
//        TimeInterval timer = DateUtil.timer();
//        if (!isRequestValid(request)) {
//            filterChain.doFilter(request, response);
//            return;
//        }
//        if (!(request instanceof ContentCachingRequestWrapper)) {
//            request = new ContentCachingRequestWrapper(request);
//        }
//        if (!(response instanceof ContentCachingResponseWrapper)) {
//            response = new ContentCachingResponseWrapper(response);
//        }
//        int status = HttpStatus.INTERNAL_SERVER_ERROR.value();
//        long startTime = System.currentTimeMillis();
//        try {
//            Map<String, Object> paramter = new HashMap<>(16);
//            paramter.put("token", request.getHeader("token"));
//            ParameterRequestWrapper wrapper = new ParameterRequestWrapper(request, paramter);
//            filterChain.doFilter(wrapper, response);
//            status = response.getStatus();
//            log.info("-------------------begin----------------------------------------");
//            log.info("HEADER: CONTENT-TYPE：{}", request.getHeader("content-type"));
//            log.info("url   : {}", request.getRequestURL().toString());
//        } finally {
//            String path = request.getRequestURI();
//            //path.startsWith(NEED_TRACE_PATH_PREFIX) &&
//            if (!Objects.equals(IGNORE_CONTENT_TYPE, request.getContentType())) {
//                String requestBody = IOUtils.toString(request.getInputStream(), "UTF-8");
//                //1. 记录日志
//                HttpTraceLog traceLog = new HttpTraceLog();
//                traceLog.setPath(path);
//                traceLog.setMethod(request.getMethod());
//                long latency = System.currentTimeMillis() - startTime;
//                traceLog.setTimeTaken(latency);
//                Enumeration<String> headerNames = request.getHeaderNames();
//                Map<String, Object> headersMap = Maps.newHashMap();
//                while (headerNames.hasMoreElements()) {
//                    String s = headerNames.nextElement();
//                    headersMap.put(s, request.getHeader(s));
//                }
//                traceLog.setRequestHeaders(JSONUtil.toJsonStr(headersMap));
//                traceLog.setTime(LocalDateTime.now().toString());
//                traceLog.setParameterMap(JSONUtil.toJsonStr(request.getParameterMap()));
//                traceLog.setStatus(status);
//                getUserBasicInfo(traceLog, request);
//                traceLog.setRequestBody(getRequestBody(request));
//                traceLog.setResponseBody(getResponseBody(response));
//                String requestUri = request.getRequestURI();//请求的Uri
//                String method = request.getMethod();          //请求的方法类型(post/get)
//                log.info("请求状态：{}  method: {}", status, method);
//                log.info("requestUri: {}", requestUri);
//                log.info("请求参数: {}", request.getParameterMap().size() > 0 ? JSONUtil.toJsonStr(request.getParameterMap()) : getRequestBody
//                        (request));
//                log.info("All ：{}", JSONUtil.toJsonStr(traceLog));
//                log.info("-------------------end请求耗时：{}毫秒-----------------------------", timer.interval());//花费毫秒数
//            }
//            updateResponse(response);
//        }
//    }
//
//    @Data
//    @Accessors(chain = true)
//    public static class HttpTraceLog {
//        private String path;
//        private String userId;
//        private String shopId;
//        private String deviceNumber;
//        private String clientVersion;
//        private String parameterMap;
//        private String requestHeaders;
//        private String method;
//        private Long timeTaken;
//        private String time;
//        private Integer status;
//        private String requestBody;
//        private String responseBody;
//    }
//
//}
